package ar.camera.thread;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

import android.net.NetworkInfo;
import android.os.Handler;
import android.os.Message;
import ar.globals.Globals;
import arserver.pojo.RegistrationItem;

public class MainClientThread implements Runnable {

	private Handler handler;
	private Socket socket;
	private DataInputStream is;
	private ObjectInputStream ois;
	private PrintStream os;
	private ObjectOutputStream oos;
	private long lastUpdate;
	private boolean isClient1;
	private boolean isClient2;
	private String[] des;
	private boolean isStopped;

	public void setDes(String[] des) {
		this.des = des;
	}

	public MainClientThread(Socket socket, Handler handler,
			boolean isClient1, boolean isClient2) {
		this.socket = socket;
		this.handler = handler;
		this.lastUpdate = System.currentTimeMillis();
		this.isClient1 = isClient1;
		this.isClient2 = isClient2;
		this.isStopped = false;
	}

	@Override
	public void run() {
		init();
		if (isClient1) {
			registerPhoneNumbersToServer(des);
		}
		if (isClient2) {
			sendStringToServer(Globals.STR_GET_REGISTRATION_LIST);
			sendStringToServer(Globals.phoneNumber);
			sendStringToServer(Globals.trackCode);
			receiveFromServerAndProcess();
			while (true) {
				if (isStopped)
					break;
				if (Globals.phoneNumberOfSharingFriend.trim().equals("")
						|| Globals.phoneNumber.trim().equals(""))
					continue;
				long current = System.currentTimeMillis();
				if (current - lastUpdate > Globals.PERIOD_OF_UPDATING) {
					NetworkInfo ni = Globals.connectivityManager
							.getActiveNetworkInfo();
					if (ni == null || !(ni.isConnected())) {
						Message msg = handler.obtainMessage(
								Globals.MSG_GET_STRING,
								"Network has been disabled");
						handler.sendMessage(msg);
						break;
					}
					lastUpdate = current;
					sendStringToServer(Globals.STR_GET_LAT_LNG);
					sendStringToServer(Globals.phoneNumberOfSharingFriend);// src
					sendStringToServer(Globals.phoneNumber); // des
					receiveFromServerAndProcess();
				}
			}
		}
	}

	public void registerPhoneNumbersToServer(String[] des) {
		Globals.registrationList = new ArrayList<RegistrationItem>();
		for (int i = 0; i < des.length; i++) {
			RegistrationItem newItem = new RegistrationItem();
			newItem.setSrcName(Globals.nickName);
			newItem.setSrcPhoneNumber(Globals.phoneNumber);
			newItem.setDesPhoneNumber(des[i]);
			newItem.setTimeStamp(System.currentTimeMillis());
			newItem.setLat(Globals.LAT);
			newItem.setLng(Globals.LNG);
			newItem.setCode(Globals.shareCode);
			Globals.registrationList.add(newItem);
		}
		sendStringToServer(Globals.STR_REGISTER_PHONE_NUMBERS);
		sendStringToServer(String.valueOf(Globals.registrationList.size()));
		for (RegistrationItem item : Globals.registrationList) {
			sendObjectToServer(item);
		}
	}

	public void shareLatLngToServer(String lat, String lng) {
		sendStringToServer(Globals.STR_SHARE_LAT_LNG);
		sendStringToServer(String.valueOf(Globals.phoneNumbersOfSharedFriends
				.size()));
		for (String desNumber : Globals.phoneNumbersOfSharedFriends) {
			RegistrationItem newItem = new RegistrationItem();
			newItem.setSrcName(Globals.nickName);
			newItem.setSrcPhoneNumber(Globals.phoneNumber);
			newItem.setDesPhoneNumber(desNumber);
			newItem.setTimeStamp(System.currentTimeMillis());
			newItem.setLat(lat);
			newItem.setLng(lng);
			newItem.setCode(Globals.shareCode);
			sendObjectToServer(newItem);
		}
	}

	private void receiveFromServerAndProcess() {
		try {
			String connection = is.readLine();
			if (connection.equals(Globals.STR_GET_REGISTRATION_LIST)) {
				String count = is.readLine();
				List<RegistrationItem> items = new ArrayList<RegistrationItem>();
				int n = Integer.valueOf(count);
				for (int i = 0; i < n; i++) {
					try {
						RegistrationItem newItem = (RegistrationItem) ois
								.readObject();
						items.add(newItem);
					} catch (ClassNotFoundException e) {
						e.printStackTrace();
					}
				}
				Message msg = handler.obtainMessage(
						Globals.MSG_GET_REGISTRATION_LIST, items);
				handler.sendMessage(msg);
			}
			if (connection.equals(Globals.STR_GET_LAT_LNG)) {
				try {
					RegistrationItem newItem = (RegistrationItem) ois
							.readObject();
					Message msg = handler.obtainMessage(
							Globals.MSG_GET_REGISTRATION_ITEM, newItem);
					handler.sendMessage(msg);
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void init() {
		try {
			is = new DataInputStream(socket.getInputStream());
			ois = new ObjectInputStream(socket.getInputStream());
			os = new PrintStream(socket.getOutputStream());
			oos = new ObjectOutputStream(socket.getOutputStream());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void sendStringToServer(String str) {
		os.println(str);
	}

	public void sendObjectToServer(Object obj) {
		try {
			oos.writeObject(obj);
			oos.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public boolean disConnect() {
		sendStringToServer(Globals.STR_DISCONNECT);
		this.isStopped = true;
		return true;
	}
}
